package xyj.sparrow.discovery.zk.bean.strategies;

import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.state.ConnectionState;
import org.apache.curator.x.discovery.ServiceCache;
import org.apache.curator.x.discovery.ServiceInstance;

import java.util.List;
import java.util.Random;
import java.util.function.Consumer;

/**
 * 监听服务实例变化 此策略在实例列表中按顺序轮换
 */
@Slf4j

public class RandomServiceListener implements ServiceListener {
    private List<ServiceInstance<Object>> instances;
    private final ServiceCache<Object> serviceCache;
    private final String serviceName;
    private final Random random = new Random();
    private final Consumer<Object> consumer;

    public RandomServiceListener(ServiceCache<Object> serviceCache, List<ServiceInstance<Object>> instances,
                                 String serviceName, Consumer<Object> consumer) {
        this.serviceCache = serviceCache;
        this.instances = instances;
        this.serviceName = serviceName;
        this.consumer = consumer;
    }

    /**
     * 服务实例发生改变
     *
     * @return void
     * @author 江南小俊
     * @since 2021/6/19 下午10:48
     **/

    @Override
    public void cacheChanged() {
        log.info("{}服务实例发生变化", serviceName);
        this.instances = serviceCache.getInstances();
        if (consumer != null) {
            consumer.accept(instances);
        }
    }

    @Override
    public void stateChanged(CuratorFramework client, ConnectionState newState) {

    }

    /**
     * 随机获取实例
     *
     * @return org.apache.curator.x.discovery.ServiceInstance<java.lang.String>
     * @author 江南小俊
     * @since 2021/6/19 下午11:42
     **/
    @Override
    public ServiceInstance<Object> getInstance() throws Exception {

        if (instances.isEmpty()) {
            //拉一次
            this.instances = serviceCache.getInstances();
            if (instances.isEmpty()) {
                return null;
            }
        }
        int thisIndex = random.nextInt(instances.size());
        return instances.get(thisIndex);
    }

    @Override
    public List<ServiceInstance<Object>> listInstance() {
        return instances;
    }
}